from datetime import datetime
from flask import session

from info.utils.response_code import RET
from . import passport_blu
from flask import request,current_app,jsonify,make_response
from info.utils.captcha.captcha import captcha
from info import redis_store,constants, db
import re
import random
from info.models import User
from info.libs.yuntongxun import sms



# 验证码
@passport_blu.route('/image_code')
def image_code():
    """
    1/获取地址栏的参数uuid编号
    2/生成验证码
    3/保存到redis中，需要try
    4/返回图片
    """
    code_id = request.args.get('code_id')
    name,text,image = captcha.generate_captcha()
    print(text)
    try:
        redis_store.setex('imagecode_'+code_id,constants.IMAGE_CODE_REDIS_EXPIRES, text)
    except Exception as e:
        current_app.logger.error(e)
        return make_response(jsonify(errno=RET.DATAERR, errmsg='保存图片验证码失败'))

    resp = make_response(image)
    resp.headers['Content-Type'] = 'image/jpg'
    return resp

# 短信验证码
@passport_blu.route("/sms_code",methods=['POST'])
def sms_code():
    """
    1/接受参数并取值，手机号，图片验证码，图片验证码uuid号，前端发送的ajax，使用request.json.get()取值判断是否有值
    2/判断手机号格式是否正确
    3/根据图片编码id找到redis中的图片验证码的字符并验证（是否能取出图片码id，能取出就保存并删除，图片码是否过期，
    验证是否一致，查询数据库都需要try
    4/判断手机号是否已经注册
    4/生成随机6位数字内容并发送短信
    5/保存到redis中短信内容
    6/返回发送成功的响应
    """
    #前端使用ajax发送的一个字典，在这取值
    mobile = request.json.get('mobile')
    imageCode = request.json.get('imageCode')
    imageCodeId = request.json.get('imageCodeId')
    if not all([mobile,imageCode,imageCodeId]):
        return jsonify(errno=RET.PARAPMERR,errmsg='参数不完整')
    #验证手机号格式
    if not re.match(r'1[3456789]\d{9}$',mobile):
        return jsonify(errno=RET.PARAMERR,errmsg='手机号格式错误')
    #取值redis中的值
    try:
        redis_imagecode = redis_store.get('imagecode_'+imageCodeId)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='获取数据失败')
    #判断值是否存在：
    if not redis_imagecode:
        return jsonify(errno=RET.NODATA,errmsg='验证码已过期')
    #存在就删除redis值
    try:
        redis_store.delete('imagecode_'+imageCodeId)
    except Exception as e:
        current_app.logger.error(e)
    #判断是否和客户端输入的值一致
    if imageCode.lower() != redis_imagecode.lower():
        return jsonify(errno=RET.DATAERR,errmsg='图片验证码不一致')
    #判断手机号是否注册
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询数据失败')
    else:
        if user:
            return jsonify(errno=RET.DATAEXIST, errmsg='手机号已注册')
    #生成6位随机数
    result = "%06d" % random.randint(0,999999)
    print(result)
    #存储到redis数据库中
    try:
        redis_store.setex('smscode_'+mobile,constants.SMS_CODE_REDIS_EXPIRES,result)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='保存数据异常')
    #发送短信
    try:
        ccp = sms.CCP()
        retsults = ccp.send_template_sms(mobile,[result,constants.SMS_CODE_REDIS_EXPIRES/60],1)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg='发送短信异常')
    #判断发送成功
    if retsults == 0:
        return jsonify(errno=RET.OK,errmsg='发送成功')
    else:
        return jsonify(errno=RET.THIRDERR, errmsg='发送失败')


# 注册
@passport_blu.route("/register",methods=["POST"])
def register():
    """
    注册接口：
    1/获取手机号，密码，短信验证码参数
    2/参数是否为空
    3/判断手机号格式
    4/从数据库取出短信验证码，然后判断是否一致，成功后删除redis中短信验证码
    5/判断手机号是否注册
    6/保存用户信息到模型类
    7/提交到数据库
    8/缓存用户信息
    """
    #获取参数json格式获取
    mobile = request.json.get('mobile')
    smscode = request.json.get('smscode')
    password = request.json.get('password')
    #判断非空
    if not all([mobile,smscode,password]):
        return jsonify(errno=RET.PARAMERR,errmsg='参数不完整')
    #判断手机号
    if not re.match(r'1[3456789]\d{9}$',mobile):
        return jsonify(errno=RET.PARAMERR,errmsg='手机号格式错误')
    #在redis中获取smscode的value值
    try:
        sms_Code = redis_store.get('smscode_'+mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='获取数据失败')
    #是否过期
    if not sms_Code:
        return jsonify(errno=RET.NODATA,errmsg='验证码已过期')
    #检查是否一致
    if sms_Code != str(smscode):
        return jsonify(errno=RET.DATAERR,errmsg='验证码不一致')
    #删除短信验证码
    try:
        redis_store.delete('smscode_'+mobile)
    except Exception as e:
        current_app.logger.error(e)
    #判断手机号是否注册
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询用户数据失败')
    else:
        if user:
            return jsonify(errno=RET.DATAERR,errmsg='手机号已经注册')
    #保存用户信息
    user = User()
    user.mobile = mobile
    user.nick_name = mobile
    user.password = password
    #提交到数据库
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg='保存用户数据失败')
    #缓存用户信息
    session['user_id'] = user.id
    session['mobile'] = user.mobile
    session['nick_name'] = user.mobile
    #返回结果
    return jsonify(errno=RET.OK,errmsg='OK')


# 登录
@passport_blu.route('/login',methods=['POST'])
def login():
    """
    1/获取参数，手机号和密码，json格式接受
    2/参数是否为空
    3/检查手机号格式
    4/根据手机号查询数据用户是否存在
    5/判断用户名和密码是否配套
    6/记录登录时间
    6/保存到数据库
    6/设置session缓存，注意与注册缓存不一致
    7/返回数据
    :return:
    """
    #获取参数
    mobile = request.json.get('mobile')
    password = request.json.get('password')
    #判断非空
    if not all([mobile,password]):
        return jsonify(errno=RET.PARAMERR,errmsg='获取参数失败')
    #判断手机号格式
    if not re.match(r'1[3456789]\d{9}$',mobile):
        return jsonify(errno=RET.PARAMERR,errmsg='手机号格式错误')
    #查询用户是否存在
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询用户数据失败')
    #判断用户名或者密码
    if user is None or not user.check_password(password):
        return jsonify(errno=RET.DATAERR,errmsg='密码错误')
    #记录登录时间
    user.last_login = datetime.now()
    #保存到数据库
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg='保存用户数据失败')
    #缓存
    session['user_id'] = user.id
    session['mobile'] = mobile
    session['nick_name'] = user.nick_name
    #返回
    return jsonify(errno=RET.OK,errmsg='OK')

#退出登录
@passport_blu.route('/logout')
def logout():
    """
    退出登录本质是清除缓存
    :return:
    """
    session.pop('user_id',None)
    session.pop('mobile',None)
    session.pop('nick_name',None)
    session.pop('is_admin', None)
    return jsonify(errno=RET.OK,errmsg='OK')